package edu.biwu.sms;

import java.time.LocalDate;
import java.util.Random;

/**
 需求：添加一个随机点名的功能，最终返回随机点到的学生对象

 就存上三个学生  索引0------小新，1-----小明，2------天天
 花花由于邮箱的格错误没有加入成功
 获取存储的有效元素个数
 */


public class StudentManagementSystem {
    /*定义一个Student类型的数组*/
    private Student[] students;

    //专门统计存储的有效学生元素个数
    private int count;

    public StudentManagementSystem(int capacity) {
        //capacity代表数组容量
        //传递一个参数代表开辟的数组空间
        this.students = new Student[capacity];
    }


    /**
     *
     * @return  返回随机取到的学生
     */
    public Student randomRollCall(){
         return students[new Random().nextInt(count)];
    }



    /**
     * 邮箱的匹配校验
     * @param student  学生对象
     * @return  返回邮箱匹配校验结果
     */
    public boolean validateStudentEmail(Student student){
        //1.健壮性判断  防空处理
        if (student==null || student.getEmall()==null) {
            return false;
        }else{
            //2.邮箱匹配判断
            return student.getEmall().matches("\\w+@\\w+\\.\\w+");
        }

    }




    /**如果返回值有多个，那么可以将多个返回值封装到一个容器中
     *
     * @param date  指定日期
     * @return  装满了满足条件的学生数组
     */

    public Student[] getStudentsEnrolledBefore(String date){
       //1.定义一个数组，该数组专门用来存储满足条件的学生信息
       Student[] temps=new Student[students.length];
       //2.遍历students中的所有信息，如果该学生的入学日期在指定日期之前，那么就将该学生的信息存入temos数组中
        for (int i = 0; i < students.length; i++) {
            Student student=students[i];

            //空指针异常错误
//            if(student!=null && student.getEnrollmentDate()!=null &&       //LocalDate.parse(date)如果不指定，就默认按照年-月-日的格式解析
//                    student.getEnrollmentDate().isBefore(LocalDate.parse(date)) ||
//                    student.getEnrollmentDate().equals(LocalDate.parse(date)));

            if(student!=null && student.getEnrollmentDate()!=null){
                if (student.getEnrollmentDate().isBefore(LocalDate.parse(date)) ||
                        student.getEnrollmentDate().isEqual(LocalDate.parse(date))){
                    addStudent(temps,student);//将当前学生满足条件条件添加到temp数组
                }
            }
        }
        return temps;
    }

    /**
     * 查询指定日期之后入学的学生信息（包含指定日期）
     * @param date 指定日期
     * @return  返回装满足条件的学生数组
     */
    public Student[] getStudentsEnrolledAfter(String date){
        //1.定义一个数组，该数组专门用来存储满足条件的学生信息
        Student[] temps=new Student[students.length];
        //2.遍历students中的所有信息，如果该学生的入学日期在指定日期之前，那么就将该学生的信息存入temos数组中
        for (int i = 0; i < students.length; i++) {
            Student student=students[i];
            if(student!=null && student.getEnrollmentDate()!=null) {
                if (student.getEnrollmentDate().isAfter(LocalDate.parse(date)) ||
                        student.getEnrollmentDate().isEqual(LocalDate.parse(date))) {
                    addStudent(temps, student);//将当前学生满足条件条件添加到temp数组
                }
            }
        }
        return temps;
    }


    /**
     *
     * @param students    指定一个数组
     * @param student     向指定数组中添加元素
     */
    public void addStudent(Student[] students, Student student) {
        if (validateStudentEmail(student)) {
            for (int i = 0; i < students.length; i++) {
                if (students[i] == null) {
                    students[i] = student;
                    count++;//存储学生对象的同时，让计数器记录系统中已经存储的学生个数
                    break;//一旦将学生信息存储好就立刻终止
                }
            }
        } else {
            System.out.println("学号：" + student.getStudentid() + ",姓名：" + student.getName()
                    + ",邮箱：" + student.getEmall() + "不符合邮箱格式添加失败！");
        }
    }


    /**
     * 添加学生
     * @param student 将来接受学生对象（中学生和小学生），对象中封装着学生的信息（姓名、学号....）
     */
    public void addStudent(Student student) {
        addStudent(students,student);
    }



    /**
     * 展示所有学生信息
     */
    public void showAllStudent() {
        showAllStudent(students);
    }

    /**
     * 展示指定学生数组的学生信息
     * @param students
     */
    public void showAllStudent(Student[] students) {
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {//如果数组中取的不是null,再进行信息展示，同时也防止空指针异常
                System.out.println((i + 1) + " " + student.toString());
            }
        }
    }




    /**
     * @param subject 指定科目，例如：“语文”
     * @return 指定学科最高成绩的学生信息
     */
    public Student findStudentWithHigestScore(String subject) {//参数为下面的方法
        int heigestScore = 0;
        Student studentWithHighestScore = null;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {
                int score = getScoreBySubject(student, subject);//存储数组中学生的某一门成绩
                if (score > heigestScore) {
                    heigestScore = score;
                    studentWithHighestScore = student;
                }
            }
        }
        return studentWithHighestScore;
    }




    /**
     * @param subject 指定科目，例如：“语文”
     * @return 指定学科最高成绩的学生信息
     */
    public Student findStudentWithLowestScore(String subject) {//参数为下面的方法
        int lowestScore = Integer.MAX_VALUE;//整数变量最大值，2的31次方-1   按住CTRL+鼠标左键可以查看
        Student studentWithlowestScore = null;
        for (int i = 0; i < students.length; i++) {
            Student student = students[i];
            if (student != null) {
                int score = getScoreBySubject(student, subject);//存储数组中学生的某一门成绩
                if (score < lowestScore) {
                    lowestScore = score;
                    studentWithlowestScore = student;
                }
            }
        }
        return studentWithlowestScore;
    }

    /**
     *获取学生某一门科目的平均分
     * @param subject  指定科目  例如：“数学”
     * @return   所有学生指定科目的平均成绩
     */
    public int getAverageScoreBySubject(String subject){
        int totalScore=0;//对所有学生某一门成绩累加求和
        int count=0;//统计数组已存储的学生对象个数
        for (int i = 0; i < students.length; i++) {
            Student student=students[i];
            if(student!=null){
                int score=getScoreBySubject(student,subject);
                totalScore +=score;
                count++;
            }
        }
        return count== 0 ? 0 : totalScore / count;
    }


    /**
     * 根据每个学生的总分数进行成绩从高到底排序，即排名
     */
    public void sortByTotalScore() {
        for (int i = 0; i < students.length - 1; i++) {
            for (int j = 0; j < students.length - i - 1; j++) {
                if (students[j] != null && students[j + 1] != null) {
                    if (students[j].getTotalScore() < students[j + 1].getTotalScore()) {
                        Student temp = students[j];
                        students[j] = students[j + 1];
                        students[j + 1] = temp;
                    }
                }
            }
        }
    }


    /**
     * @param studentid   学生学号
     * @return   根据学生学号，查询到学生信息(封装到学生对象中)
     */
    public Student findStudentById(int studentid){
        for (int i = 0; i < students.length; i++) {
            Student student=students[i];
            if(student!=null && student.getStudentid()==studentid){//如果当前的学生存在，并且当前学生的学号等于所要查找的学号就直接返回该学生
                return student;
            }
        }
        return null;//如果程序执行到该位置，说明找不到学号为studentid的学生，就返回null
    }




    /**
     * @param student 学生对象
     * @param subject 科目名称
     * @return 当前学生指定科目的成绩
     */
    private int getScoreBySubject(Student student, String subject) {

//        switch(subject){
//            case "语文":
//                return student.getChineseScore();
//            case "数学":
//                return student.getMathScore();
//            case "历史":
//                if (student instanceof MiddleStudent) {
//                    MiddleStudent ms=(MiddleStudent) student;
//                    return ms.getHistoryScore();
//                }else{
//                    return 0;
//                }
//            case "物理":
//                if (student instanceof MiddleStudent) {
//                    MiddleStudent ms=(MiddleStudent) student;
//                    return ms.getPhysicsScore();
//                }else {
//                    return 0;
//                }
//            default:
//                return 0;
//        }
//    }
//或者用：
        //JDK新特性
        switch (subject) {
            case "语文" -> {
                return student.getChineseScore();
            }
            case "数学" -> {
                return student.getMathScore();
            }
            case "历史" -> {
                if (student instanceof MiddleStudent middleStudent) {
                    return middleStudent.getHistoryScore();
                }
            }
            case "物理" -> {
                if (student instanceof MiddleStudent middleStudent) {
                    return middleStudent.getPhysicsScore();
                }
            }
//            default -> {
//                return 0;
//            }转换为下面的哪一行
        }
        return 0;//传递的subject没有找到就返回0
    }



}